import { Alert, CodeGroup, ContentByFramework } from '@/components/forMdx';

export const metadata = {
  description: "Guidance on testing Jazz apps."
};

# Testing Jazz Apps

As you develop your Jazz app, you might find yourself needing to test functionality relating to sync, identities, and offline behaviour. The `jazz-tools/testing` utilities provide helpers to enable you to do so.

## Core test helpers
Jazz provides some key helpers that you can use to simplify writing complex tests for your app's functionality.

### `setupJazzTestSync`

This should normally be the first thing you call in your test setup, for example in a `beforeEach` or `beforeAll` block. This function sets up an in-memory sync node for the test session, which is needed in case you want to test data synchronisation functionality. Test data is not persisted, and no clean-up is needed between test runs.

<CodeGroup>
```ts index.ts#SetupJazzTestSync
```
</CodeGroup>

### `createJazzTestAccount`
After you've created the initial account using `setupJazzTestSync`, you'll typically want to create user accounts for running your tests.

You can use `createJazzTestAccount()` to create an account and link it to the sync node. By default, this account will become the currently active account (effectively the 'logged in' account).

You can use it like this:

<CodeGroup>
```ts index.ts#CreateTestAccount
```
</CodeGroup>

#### `AccountSchema`
This option allows you to provide a custom account schema to the utility to be used when creating the account. The account will be created based on the schema, and all attached migrations will run.

#### `isCurrentActiveAccount`
This option (disabled by default) allows you to quickly switch to the newly created account when it is created.

<CodeGroup preferWrap>
```ts index.ts#CurrentlyActive
```
</CodeGroup>

#### `creationProps`
This option allows you to specify `creationProps` for the account which are used during the account creation (and passed to the migration function on creation).

## Managing active Accounts
During your tests, you may need to manage the currently active account after account creation, or you may want to simulate behaviour where there is no currently active account.

### `setActiveAccount`
Use `setActiveAccount()` to switch between active accounts during a test run.

You can use this to test your app with multiple accounts.

<CodeGroup preferWrap>
```ts index.ts#SetActiveAccount
```
</CodeGroup>

### `runWithoutActiveAccount`
If you need to test how a particular piece of code behaves when run without an active account.

<CodeGroup preferWrap>
```ts index.ts#RunWithoutAccount
```
</CodeGroup>

## Managing Context
To test UI components, you may need to create a mock Jazz context.

<ContentByFramework framework="react">
  In most cases, you'd use this for initialising a provider. You can see how we [initialise a test provider for React tests here](https://github.com/garden-co/jazz/blob/main/packages/jazz-tools/src/react-core/testing.tsx), or see how you could [integrate with `@testing-library/react` here](https://github.com/garden-co/jazz/blob/main/packages/jazz-tools/src/react-core/tests/testUtils.tsx).
</ContentByFramework>

<ContentByFramework framework="svelte">
 You can render your components for testing by passing a mocked Jazz context to the `@testing-library/svelte` `render` helper.

 [You can see an example of how we do that here](https://github.com/garden-co/jazz/blob/main/packages/jazz-tools/src/svelte/tests/testUtils.ts).
</ContentByFramework>

<ContentByFramework framework="vanilla">
The `TestJazzContextManager` mocks the `JazzContextManager` to allow you to instantiate a Jazz context as a user or a guest, allowing you to run tests which depend on an authenticated or a guest session.

You'll normally use either:

* `TestJazzContextManager.fromAccount(account, props?)` to simulate a logged-in context. You can pass `isAuthenticated: false` as an option to simulate an [anonymous user](docs/key-features/authentication/authentication-states#anonymous-authentication).
* `TestJazzContextManager.fromGuest({ guest }, props?)` to simulate a [guest context](/docs/key-features/authentication/authentication-states#guest-mode).

You can also use `TestJazzContextManager.fromAccountOrGuest()` to allow you to pass either.
</ContentByFramework>

### Simulating connection state changes
You can use `MockConnectionStatus.setIsConnected(isConnected: boolean)` to simulate disconnected and connected states (depending on whether `isConnected` is set to `true` or `false`).

## Next Steps
You're ready to start writing your own tests for your Jazz apps now. For further details and reference, you can check how we do our testing below.

* [Unit test examples](https://github.com/garden-co/jazz/tree/main/packages/jazz-tools/src/tools/tests)
* [End-to-end examples](https://github.com/garden-co/jazz/tree/main/tests/e2e/tests)

<ContentByFramework framework="react">
* [React-specific tests](https://github.com/garden-co/jazz/tree/main/packages/jazz-tools/src/react-core/tests)
</ContentByFramework>

<ContentByFramework framework="svelte">
* [Svelte-specific tests](https://github.com/garden-co/jazz/tree/main/packages/jazz-tools/src/svelte/tests)
</ContentByFramework>
